package com.uphone.mvpdemo.http;


import com.franmontiel.persistentcookiejar.PersistentCookieJar;
import com.franmontiel.persistentcookiejar.cache.SetCookieCache;
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;
import com.radish.baselibrary.utils.LogUtils;
import com.radish.baselibrary.utils.SharedPreferencesHelper;
import com.uphone.mvpdemo.MyApp;
import com.uphone.mvpdemo.util.CommonUtil;

import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by hzy on 2019/1/10
 * 网络请求
 *
 * @author hzy
 */
public class HttpManager {

    private Retrofit mRetrofit;
    private HashMap<Class, Retrofit> mServiceHashMap = new HashMap<>();
    private ConcurrentHashMap<Class, Object> cachedApis = new ConcurrentHashMap<>();
    private PersistentCookieJar cookieJar;

    public HttpManager() {
        cookieJar = new PersistentCookieJar(new SetCookieCache(), new
                SharedPrefsCookiePersistor(MyApp.getInstance()));
        // init okhttp 3 logger
        HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor();
        logInterceptor.setLevel(HttpLoggingInterceptor.Level.NONE);
        // int okhttp
        OkHttpClient client = new OkHttpClient.Builder()
                .retryOnConnectionFailure(true)
                .connectTimeout(15, TimeUnit.SECONDS)
                .readTimeout(45, TimeUnit.SECONDS)
                .writeTimeout(55, TimeUnit.SECONDS)
                .addInterceptor(logInterceptor)
                .addInterceptor(chain -> {
                    Request request = chain.request();
                    String token = CommonUtil.getStr(SharedPreferencesHelper.getToken());
                    Request request1 = request
                            .newBuilder()
                            .header("token", token)
                            .method(request.method(), request.body()).build();
                    Response response = chain.proceed(request1);
                    MediaType mediaType = response.body().contentType();
                    String content = response.body().string();
                    StringBuilder builder = new StringBuilder("\n网络请求:" + request.toString() + "\ntoken:" + token);
                    String method = request.method();
                    if ("POST".equals(method)) {
                        StringBuilder sb = new StringBuilder();
                        if (request.body() instanceof FormBody) {
                            FormBody body = (FormBody) request.body();
                            for (int i = 0; i < body.size(); i++) {
                                sb.append(body.encodedName(i) + "=" + body.encodedValue(i) + ",");
                            }
                            if (sb.length() > 0) {
                                sb.delete(sb.length() - 1, sb.length());
                            }
                            builder.append("\n参数:{" + sb.toString() + "}");
                        }
                    }
                    builder.append("\n返回数据:" + content);
                    LogUtils.e("" + builder.toString());
                    return response.newBuilder()
                            .body(ResponseBody.create(mediaType, content))
                            .build();
                })
                .cookieJar(cookieJar)
                .build();

        // int retrofit
        mRetrofit = new Retrofit.Builder()
                .baseUrl(ApiService.ServiceUrl)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(StringConverterFactory.create())
                .build();

        mServiceHashMap.put(ApiService.class, mRetrofit);
    }


    public <T> T getService(Class<T> clz) {
        Object obj = cachedApis.get(clz);
        if (obj != null) {
            return (T) obj;
        } else {
            Retrofit retrofit = mServiceHashMap.get(clz);
            if (retrofit != null) {
                T service = retrofit.create(clz);
                cachedApis.put(clz, service);
                return service;
            } else {
                return null;
            }
        }
    }
}